package com.server;

import com.Utils;
import com.gooddies.events.Lookup;
import com.swingson.exceptions.ErrorMessageException;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    private ServerSocket serverSocket;
    private Client client;
    private final ArtNetProcessor artNetProcessor = new ArtNetProcessor();
    private final byte[] tempSendingBuffer = new byte[39 * 78 * 3];

    public boolean isUp() {
        return serverSocket != null && !serverSocket.isClosed();
    }

    public ArtNetProcessor getArtNetProcessor() {
        return artNetProcessor;
    }

    public BufferedImage getLastImageFromClient() {
        if (client == null) {
            return null;
        }
        return client.getLastImage();
    }

    private void disconnectClient() {
        if (client != null) {
            System.out.println("Disconnect client");
            client.tryToCloseClient();
            client = null;
        }
        System.gc();
    }

    public void start() {
        if (isUp()) {
            throw new ErrorMessageException("Server already started");
        }

        try {
            serverSocket = new ServerSocket(8090);
            Thread thread = new Thread() {
                @Override
                public void run() {
                    while (isUp()) {
                        try {
                            Socket socket = serverSocket.accept();
                            disconnectClient();
                            System.out.println("Client connected " + socket.getInetAddress());
                            client = new Client(socket, Server.this);
                            client.start();
                        } catch (Throwable ex) {
                            ex.printStackTrace();
                            disconnectClient();
                            serverSocket = null;
                        }
                    }
                }
            };

            thread.start();
            Lookup.getDefault().fire("serverstatus", true);
            System.out.println("Server started");
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new ErrorMessageException(ex.getMessage());
        }
    }

    public void resendPictureToClient(BufferedImage picture) {
        Utils.copyImageToBuffer(picture, tempSendingBuffer);

        if (client != null && client.isReadyToReceivePicture()) {
            client.sendPicture(tempSendingBuffer);
        }
    }

    public void stop() {
        if (isUp()) {
            disconnectClient();

            try {
                serverSocket.close();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
                return;
            }

            serverSocket = null;
            Lookup.getDefault().fire("serverstatus", false);
            System.gc();
        }
    }
}
